/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
 *
 */

import path from 'path';

import { cloneDeep } from '@baize/wdk';
import { isSubPath } from '@ohos/hvigor-common';
import { FileSet, Input, TaskInputValue, InputFile } from '@ohos/hvigor';
import {
  COMPILED_IMPORTEE_CACHE_FILE_NAME, DIRECT_IMPORTEE_CACHE_FILE_NAME,
  NON_ENTRY_IMPORTEE_CACHE_FILE_NAME,
  PkgContextInfoOpt
} from '@ohos/hvigor-arkts-compose';
import fse from 'fs-extra';

import { parsingProfileName } from '../../common/common-util.js';
import { findTargetProduct } from '../../common/find-target-product.js';
import { projectOhosConfigManager } from '../../common/global/project-ohos-config-manager.js';
import { BuildArtifactConst, BuildDirConst } from '../../const/build-directory-const.js';
import { AbilityConst, ArktSTaskConst, CommonConst, ValidateRegExp } from '../../const/common-const.js';
import { CodeType } from '../../enum/code-type-enum.js';
import { CoreModuleModelImpl } from '../../model/module/core-module-model-impl.js';
import { ProjectModelImpl } from '../../model/project/project-model-impl.js';
import { TargetSourceSetModel } from '../../model/source-set/source-set-model.js';
import { AppOpt } from '../../options/build/app-ohos-config.js';
import { AppJson } from '../../options/configure/app-json-options.js';
import { ModuleJson } from '../../options/configure/module-json-options.js';
import { RouterMapOptions } from '../../options/configure/router-map-options.js';
import { StartupOptions } from '../../options/configure/startup-options.js';
import { Dependency, DependencyEnum, DependencyType } from '../../project/dependency/core/dependency-interface.js';
import { DependencyManager } from '../../project/dependency/dependency-manager.js';
import { toUnixPath } from '../../utils/copy-resources-util.js';
import { FileUtil } from '../../utils/file-util.js';
import { HarTargetUtil } from '../../utils/har-target-util.js';
import { getJson5Obj } from '../../utils/json-util.js';
import { ohPackageLoader } from '../../utils/loader/file/oh-package-loader.js';
import { resModelLoader } from '../../utils/loader/file/res-model-loader.js';
import { OhosLogger } from '../../utils/log/ohos-logger.js';
import { generateOhmUrlForSourceFile } from '../../utils/ohmurl-utils.js';
import { getPropertyKeepDependency } from '../../utils/parameter-utils.js';
import { validatePackageBySystemHspModel } from '../../utils/validate/validate-systemHsp.js';
import { ValidateUtil } from '../../utils/validate/validate-util.js';
import { pathParamsOpt } from '../../validate/dependency-tag-validate.js';
import { AbstractProcessHarArtifacts } from '../abstract/abstract-process-har-artifacts.js';
import { CacheNativeLibs } from '../cache-native-libs.js';
import { TaskNames } from '../common/task-names.js';
import { CompileResource } from '../compile-resource.js';
import { TargetTaskService } from '../service/target-task-service.js';
import { OhPackageJsonOpt } from '../task/ohos-har-task.js';
import { ProcessObfuscationFiles } from './process-obfuscation-files.js';
import { InjectUtil } from '../../utils/inject-util.js';
import { getLocalDependencyBuildOptions } from '../../utils/dependency-util.js';
import { getCustomTypePathIfExists } from '../../utils/build-profile-utils.js';

import Task = TaskNames.Task;
import AppOptObj = AppJson.AppOptObj;
import ModuleOptObj = ModuleJson.ModuleOptObj;
import RouterMapObj = RouterMapOptions.RouterMapObj;

/**
 * 收集打包需要用的构建产物
 */
export class ProcessHarArtifacts extends AbstractProcessHarArtifacts {
  protected logger = OhosLogger.getLogger(ProcessHarArtifacts.name);
  private readonly arkTsCompiledOutputDir: string;
  private readonly abilities = AbilityConst.UI_ABILITY;
  private readonly extensionAbilities = AbilityConst.EXTENSION_ABILITY;
  protected readonly pacJsonFilePath: string;

  // target相关属性
  private readonly appOptObj: AppOptObj;
  private readonly targetModuleOptObj: ModuleOptObj;
  private readonly targetJsonPath: string;
  private readonly compiledAbcOutputDir: string;
  private readonly declaredFilesOutputDir: string;
  private readonly ohPkgMetadataResDir: string[];
  private nonEntryImportees: string[];
  private compiledPackageNames: string[] = [];
  private npmImportees: string[] = [];
  @Input() private affectsCompilationDependencyKeys: string[] = [];
  @Input() private globalAffectsCompilationDependencyKeys: string[] = [];

  constructor(taskService: TargetTaskService) {
    super(taskService, Task.PROCESS_HAR_ARTIFACTS);

    // output  dir
    this.arkTsCompiledOutputDir = path.resolve(this.pathInfo.getInterMediatesLoaderOutPath());
    this.compiledAbcOutputDir = path.resolve(this.arkTsCompiledOutputDir, CodeType.ETS);
    this.declaredFilesOutputDir = this.pathInfo.getIntermediatesEtsTgzPath(this.moduleName);
    const appRes = (this.projectModel as ProjectModelImpl).getAppRes();
    this.appOptObj = appRes.getAppResOpt();
    const targetSourceSetModel: TargetSourceSetModel = taskService.getTargetData().getModuleSourceSetModel() as TargetSourceSetModel;
    const targetRes = targetSourceSetModel.getModuleTargetRes();
    this.targetModuleOptObj = targetRes.getModuleJsonOpt();
    this.targetJsonPath = targetRes.getJsonPath();
    this.pacJsonFilePath = this.pathInfo.getIntermediatesPacJsonPath();
    this.ohPkgMetadataResDir = [];
    this.nonEntryImportees = [];
  }

  get isBundledDependencies(): boolean {
    return this.targetService.isBundledDependencies();
  }

  get isNativeStripped(): boolean {
    return this.targetService.getBuildOption()?.nativeLib?.debugSymbol?.strip ?? true;
  }

  @Input() private get isByteCodeHarOptimize() {
    return InjectUtil.isByteCodeHarOptimize();
  }

  @Input() private get shouldPackSourceMaps(): boolean {
    // 非字节码har，不需要打包sourceMaps
    if (!this.targetService.isByteCodeHar()) {
      return false;
    }
    const isCustomPack = this.targetService.getBuildOption()?.arkOptions?.packSourceMap;
    // 配置优先
    if (typeof isCustomPack !== 'undefined') {
      return isCustomPack;
    }
    // 如果不存在配置，则debug模式下需要打包
    return this.targetService.isDebug();
  }

  @InputFile() private get insightIntentJsonPath() {
    return path.resolve(this.pathInfo.getModuleSrcMainResourceBaseProfilePath(), BuildArtifactConst.INSIGHT_INTENT_JSON);
  }

  @Input() private get customTypes(): string[] | undefined {
    return this.targetService.getCustomTypes();
  }

  declareInputs(): Map<string, TaskInputValue> {
    const appOptFromConfig: AppOpt = cloneDeep(projectOhosConfigManager.getOverrides()?.appOpt);
    const declareInputs = super
      .declareInputs()
      .set('bundleType', appOptFromConfig?.bundleType ?? findTargetProduct(this.service.getProjectModel()).bundleType ?? this.projectModel.getBundleType())
      .set('isByteCodeHar', this.targetService.isByteCodeHar())
      .set('harLocalDependencyCheck', !!this.targetService.getBuildOption().strictMode?.harLocalDependencyCheck)
      .set('isBundledDependencies', this.isBundledDependencies)
      .set('nonEntryImportees', this.nonEntryImportees)
      .set('isDebug', this.targetService.isDebug())
      .set('isNativeStripped', this.isNativeStripped);
    declareInputs.set('appStartupFileName', this.appStartupFileName ?? '');
    declareInputs.set('isOpenSource', this.targetService.isOpenSource());
    const targetDirectories = this.targetService.getTargetData().getTargetOpt().resource?.directories;
    if (targetDirectories) {
      declareInputs.set('targetDirectories', targetDirectories);
    }
    return declareInputs;
  }

  declareInputFiles(): FileSet {
    const fileSet = super.declareInputFiles();

    if (fse.existsSync(this.pathInfo.getIntermediatesPkgContextInfoPath())) {
      fileSet.addEntry(this.pathInfo.getIntermediatesPkgContextInfoPath());
    }
    if (this.appStartupPath && fse.existsSync(this.appStartupPath)) {
      fileSet.addEntry(this.appStartupPath);
    }
    if (fse.existsSync(this.intermediateTempStartupFilePath)) {
      fileSet.addEntry(this.intermediateTempStartupFilePath);
    }
    if (fse.existsSync(this.pacJsonFilePath)) {
      fileSet.addEntry(this.pacJsonFilePath);
    }
    return fileSet;
  }

  declareOutputFiles(): FileSet {
    return super.declareOutputFiles().addEntry(path.resolve(this.taskTmpDir, CommonConst.PAC_JSON));
  }

  async beforeAlwaysAction(): Promise<void> {
    await super.beforeAlwaysAction();
    this.collectNonEntryImportees();
    this.collectCompiledAndNpmImportees();
    if (this.isByteCodeHarOptimize) {
      this.processDirectImportees();
      this.processAllImportees();
    }
    this.warnWhenPackSourceMapsInReleaseMode();
  }

  private warnWhenPackSourceMapsInReleaseMode() {
    if (!this.targetService.isDebug() && this.shouldPackSourceMaps) {
      this.logger.warn(
        `The sourceMaps.map file will be packed into the HAR in release mode. This can potentially lead to code asset leakage within the HAR.
               To prevent this, set packSourceMap to false.`
      );
    }
  }

  protected getImporteesCachePath(cacheFileName: string): string {
    return super.getImporteesCachePath(cacheFileName,'HarCompileArkTS');
  }

  initTaskDepends() {
    this.declareDependsList(CacheNativeLibs.name, CompileResource.name);
    this.addSpecialDepends();
  }

  addSpecialDepends() {
    if (this._harExtendInfo.isObfuscatedHar()) {
      const useRollupETS = this.sdkInfo.hasRollUpPluginInEtsLoader;
      this.declareDepends(useRollupETS ? 'HarCompileArkTS' : 'HarBuildArkTS');
    } else {
      // 开源library单独执行arkTS代码检查, 闭源library集成在代码编译流程中
      this.declareDepends(ArktSTaskConst.LINT_ARKTS);
    }

    // 开源har包也要修改worker字段
    this.declareDepends(this.moduleModel.isOhpmProject() ? Task.PROCESS_OH_PACKAGE_JSON.name : Task.PROCESS_PACKAGE_JSON.name);
    this.declareDepends(ProcessObfuscationFiles.name);
  }

  copyCompiledSourceFileToTempDir(): void {
    if (!this.targetService.isByteCodeHar()) {
      // 拷贝编译后的ArkTs源码
      if (fse.existsSync(this.arkTsCompiledOutputDir)) {
        fse.copySync(this.arkTsCompiledOutputDir, this.taskTmpDir);
      }
      return;
    }

    if (fse.existsSync(this.compiledAbcOutputDir)) {
      fse.copySync(this.compiledAbcOutputDir, path.join(this.taskTmpDir, path.basename(this.compiledAbcOutputDir)));
    }
    if (fse.existsSync(this.declaredFilesOutputDir)) {
      fse.copySync(this.declaredFilesOutputDir, this.taskTmpDir);

      // 移除掉build目录
      const buildDir = path.resolve(this.taskTmpDir, this.pathInfo.getBuildRoot());
      if (fse.existsSync(buildDir)) {
        fse.removeSync(buildDir);
      }
    }
  }

  /**
   * 处理字节码har的bundledDependencies源码依赖资源
   */
  processBundleDepRes() {
    if (!this.targetService.isBundledDependencies()) {
      return;
    }

    const DEFAULT_RES_DIR = `${BuildDirConst.SRC}${path.sep}${BuildDirConst.MAIN}${path.sep}${BuildDirConst.RESOURCES}`;
    const directories = this.targetService.getTargetData().getTargetOpt().resource?.directories;
    if (!directories?.length) {
      this.ohPkgMetadataResDir.push(DEFAULT_RES_DIR);
    } else {
      this.ohPkgMetadataResDir.push(...directories);
    }

    const dep2ConfigMap = HarTargetUtil.getDep2ConfigMap(this.targetService);
    if (!dep2ConfigMap) {
      return;
    }
    dep2ConfigMap.dep2Resources.forEach((resourcesDir, dependency) => {
      this.copyBundledDepRes(resourcesDir, dependency);
    });
  }

  /**
   * 拷贝字节码har的bundledDependencies源码依赖的资源目录
   * @param resourcesDir
   * @param dependency
   * @private
   */
  private copyBundledDepRes(resourcesDir: string[], dependency: Dependency): void {
    const ohPackageJsonOpt = getJson5Obj(path.resolve(dependency.getDependencyRootPath(), CommonConst.OH_PACKAGE_JSON5));
    resourcesDir.forEach((dir) => {
      this.ohPkgMetadataResDir.push(`${dir}-${ohPackageJsonOpt.name}`);
      const srcPath = path.resolve(dependency.getDependencyRootPath(), dir);
      if (fse.existsSync(srcPath)) {
        const destPath = path.resolve(this.taskTmpDir, BuildDirConst.SRC, BuildDirConst.MAIN, `${path.basename(dir)}-${ohPackageJsonOpt.name}`);
        fse.mkdirsSync(destPath);
        FileUtil.copyDir(srcPath, destPath);
      }
    });
  }

  copyOtherGenerateFiles(): void {
    if (this._harExtendInfo.isObfuscatedHar()) {
      fse.readdirSync(this.generateDir).forEach((srcPath) => {
        const src = path.resolve(this.generateDir, srcPath);
        fse.copySync(src, path.resolve(this.taskTmpDir, srcPath));
      });
    } else {
      // 现在开源的也从这里拷贝oh-package.json5，虽然现在只生成了一个文件，但还是区分一下逻辑
      try {
        fse.copySync(
          ohPackageLoader.getNodeOhPackagePath(path.resolve(this.generateDir, this.isOhpmProject ? CommonConst.OH_PACKAGE_JSON5 : CommonConst.PACKAGE_JSON)),
          ohPackageLoader.getNodeOhPackagePath(path.resolve(this.taskTmpDir, this.isOhpmProject ? CommonConst.OH_PACKAGE_JSON5 : CommonConst.PACKAGE_JSON)),
        );
      } catch (e: any) {
        this.logger.warn(e.message);
      }
    }
  }

  /**
   * 复制pac.json5文件到产物中
   *
   * @private
   */
  copyIntermediatePacToTempDir() {
    if (fse.existsSync(this.pacJsonFilePath)) {
      fse.copySync(this.pacJsonFilePath, path.resolve(this.taskTmpDir, CommonConst.PAC_JSON));
    }
  }

  /**
   * 处理har包时需要将中间产物资源目录下的routerMap拷贝至cache目录下
   * @private
   */
  processHarRouterMap(): void {
    const moduleJsonPath = this.moduleModel.getJsonPathByTargetName(this.targetName);
    const moduleJsonObj: ModuleOptObj = resModelLoader.getModuleJson(moduleJsonPath);
    const routerMap = moduleJsonObj.module.routerMap;
    const routerMapFileName = parsingProfileName(routerMap);
    if (!routerMapFileName) {
      return;
    }
    const intermediateRouterMapJsonPath = path.resolve(this.targetData.getPathInfo().getIntermediatesResProfilePath(), `${routerMapFileName}.json`);
    const tempRouterMapJsonPath = path.resolve(
      this.taskTmpDir,
      BuildDirConst.SRC,
      BuildDirConst.MAIN,
      BuildDirConst.RESOURCES_BASE_PROFILE_DIR,
      `${routerMapFileName}.json`,
    );
    const routerMapJsonObj = getJson5Obj(intermediateRouterMapJsonPath);

    if (!this.targetService.isOpenSource()) {
      routerMapJsonObj.routerMap.forEach((routerMapObj: RouterMapObj) => {
        const obfuscatedPageSourceFile = this.getObfuscatedPageSourceFile(this.moduleModel, routerMapObj, this.getObfNameCacheObj());
        if (!obfuscatedPageSourceFile) {
          return;
        }

        Object.assign(routerMapObj, { pageSourceFile: obfuscatedPageSourceFile });
      });
    }

    routerMapJsonObj.routerMap.map((routerMapObj: RouterMapObj) => delete routerMapObj.originalSuffix);
    fse.writeFileSync(tempRouterMapJsonPath, JSON.stringify(routerMapJsonObj));
  }

  /**
   * 处理启动框架配置相关，修改res目录下启动框架配置文件内容
   */
  processHarResStartupConfig() {
    const startupFileName = this.appStartupFileName ?? 'startup_config';
    const intermediateResStartupFilePath = path.resolve(this.targetData.getPathInfo().getIntermediatesResProfilePath(), `${startupFileName}.json`);
    if (!fse.existsSync(intermediateResStartupFilePath)) {
      return;
    }
    const startupMergedOptions: StartupOptions | undefined = getJson5Obj(intermediateResStartupFilePath);
    if (!startupMergedOptions) {
      return;
    }
    // 得到当前target正确的资源路径
    const targetResPath = this.getTargetResPath(startupFileName);
    if (!targetResPath) {
      return;
    }
    const tempStartupJsonPath = path.resolve(this.taskTmpDir, targetResPath);
    startupMergedOptions.startupTasks?.forEach((startupTask) => {
      delete startupTask.moduleName;
      delete startupTask.srcEntryAbsolutePath;
      delete startupTask.startupConfigPath;
      if (!this.targetService.isOpenSource()) {
        startupTask.srcEntry = this.getObfuscationSrcEntryPath(this.moduleModel, startupTask.srcEntry, this.getObfNameCacheObj()) ?? startupTask.srcEntry;
      }
    });
    startupMergedOptions.appPreloadHintStartupTasks?.forEach((appPreloadHintStartupTask) => {
      delete appPreloadHintStartupTask.moduleName;
      delete appPreloadHintStartupTask.startupConfigPath;
      delete appPreloadHintStartupTask.isRemoteByteCodeHar;
    });
    fse.writeFileSync(tempStartupJsonPath, JSON.stringify(startupMergedOptions));
  }

  /**
   * 打包har之前，获取当前target正确启动框架配置文件路径：设置了directories则从directories里找，没有设置directories则返回默认目录
   * @param startupFileName
   * @private
   */
  private getTargetResPath(startupFileName: string) {
    const directories = this.targetService.getTargetData().getTargetOpt()?.resource?.directories;
    if (directories?.length) {
      for (let i = 0; i < directories.length; i++) {
        const directory = directories[i];
        const startupConfigRes = path.join(directory, CommonConst.BASE_PROFILE, `${startupFileName}.json`);
        const startupConfigFile = FileUtil.convertToAbsolutePath(startupConfigRes, this.targetService.getTargetData().getPathInfo().getModulePath());
        if (fse.existsSync(startupConfigFile)) {
          return startupConfigRes;
        }
      }
    } else {
      const defaultStartupResPath = path.join(BuildDirConst.SRC, BuildDirConst.MAIN, BuildDirConst.RESOURCES_BASE_PROFILE_DIR, `${startupFileName}.json`);
      const defaultStartupFilePath = FileUtil.convertToAbsolutePath(defaultStartupResPath, this.targetService.getTargetData().getPathInfo().getModulePath());
      return fse.existsSync(defaultStartupFilePath) ? defaultStartupResPath : undefined;
    }
    return undefined;
  }

  /**
   * 如果是混淆场景，得到srcEntry的混淆路径
   * @param moduleModel
   * @param srcEntry
   * @param obfNameCacheJsonObj
   * @private
   */
  private getObfuscationSrcEntryPath(moduleModel: CoreModuleModelImpl, srcEntry: string, obfNameCacheJsonObj: any): string | undefined {
    let obfuscationSrcEntry: string | undefined;
    const hasUseTsHarFileSuffix = this.hasUseTsHarField() ? '.ts' : '.js';
    const fileSuffix = FileUtil.getFileSuffix(srcEntry);
    if (ValidateRegExp.DYNAMIC_IMPORT_FILE_SUFFIX_REG_EXP.test(fileSuffix)) {
      obfuscationSrcEntry = `${srcEntry.substring(0, srcEntry.lastIndexOf('.'))}${hasUseTsHarFileSuffix}`;
    }
    const moduleName = moduleModel.getName();
    const srcEntryPath = path.join(moduleName, BuildDirConst.SRC, BuildDirConst.MAIN, srcEntry);
    const normalizedSrcEntry = FileUtil.normalizePathSeparator(srcEntryPath);
    if (Object.prototype.hasOwnProperty.call(obfNameCacheJsonObj, normalizedSrcEntry)) {
      obfuscationSrcEntry = obfNameCacheJsonObj[normalizedSrcEntry].obfName;
    }
    const relativeObfSrcEntry =
      path.relative(FileUtil.normalizePathSeparator(path.join(moduleName, BuildDirConst.SRC, BuildDirConst.MAIN)), obfuscationSrcEntry ?? normalizedSrcEntry);
    return relativeObfSrcEntry.replace(path.extname(relativeObfSrcEntry), hasUseTsHarFileSuffix);
  }

  /**
   * 对于字节码HAR，由于代码已经编进abc，且，该abc在集成的时候是直接合并到hap/hsp中，不再有源码参与编译的流程
   * 所以，在集成的时候，就造成了字节码HAR本身的workers、动态import对应文件的ohmurl丢失，导致运行时报错
   * 这里要将这些丢失的ohmurl写入declarationEntry，在集成的时候写入loader.json
   *
   * 新增：意图框架的sryEntry也需要收集到declarationEntry中
   * @param pkgJson
   * @private
   */
  private processDeclarationEntry(pkgJson: OhPackageJsonOpt): void {
    if (!this.targetService.isByteCodeHar()) {
      this.logger.debug('Since current module is not byte code har, just return.');
      return;
    }

    // 动态import
    const dynamicSources = pkgJson.metadata?.runtimeOnly?.sources || [];
    const workerSources = pkgJson.metadata?.workers || [];

    // 字节码HAR不再需要
    delete pkgJson.metadata?.workers;
    delete pkgJson.metadata?.runtimeOnly?.sources;

    const pkgContextInfoPath = this.pathInfo.getIntermediatesPkgContextInfoPath();
    const pkgContextInfos = getJson5Obj(pkgContextInfoPath);
    const pkgContextInfo = pkgContextInfos[this.packageJsonObj.name];
    if (!pkgContextInfo) {
      this.logger.debug(`Can not find package context information with package name: ${this.packageJsonObj.name}`);
      return;
    }

    const declarationEntry: string[] = [];
    if (this.isBundledDependencies) {
      // 收集本地或远程源码har依赖的部分配置信息的ohmurl并写入declarationEntry
      // worker
      this.collectConfigOhmurl(HarTargetUtil.getDep2ConfigMap(this.targetService)?.dep2Workers, pkgContextInfos, declarationEntry);

      // runtimeOnly
      this.collectRuntimeOnlyOhmurl(pkgContextInfos, declarationEntry);

      // routerMapObj-pageSourceFile
      this.collectConfigOhmurl(HarTargetUtil.getDep2ConfigMap(this.targetService)?.dep2RouterMapObjPageSourceFiles, pkgContextInfos, declarationEntry);
    }

    // ability-srcEntry
    this.collectByteCodeHarAbilityOhmurl(pkgContextInfos, declarationEntry);

    // 字节码har启动框架startupTasks处理
    this.collectByteCodeHarStartupTasks(declarationEntry);

    // 字节码har收集意图框架编译入口文件
    this.collectByteCodeHarInsightIntentSrcEntry(pkgContextInfos, declarationEntry);

    const sources = [...workerSources, ...dynamicSources];
    if (sources.length) {
      sources.forEach((source) => {
        declarationEntry.push(generateOhmUrlForSourceFile(pkgContextInfo, source.replace(/^\.\//, '')));
      });
    }

    pkgJson.metadata = {
      ...pkgJson.metadata,
      declarationEntry,
    };
  }

  private processDirectImportees(): void {
    // 非字节码HAR不处理
    if (!this.targetService.isByteCodeHar()) {
      return;
    }
    const importeesPath = this.getImporteesCachePath(DIRECT_IMPORTEE_CACHE_FILE_NAME);
    const { compileDependencyKeys, globalCompileDependencyKeys } = this.collectDirectAffectsCompilationDependencyKeys(importeesPath);
    ([compileDependencyKeys, globalCompileDependencyKeys]).forEach(ary => {
      // 排序，保持增量稳定性
      ary.sort((a, b) => (a > b ? 1 : -1));
    });
    this.affectsCompilationDependencyKeys = compileDependencyKeys;
    this.globalAffectsCompilationDependencyKeys = globalCompileDependencyKeys;
  }

  private getDependencyRuntimePackages(dependency: Dependency, moduleName2TargetName: Map<string, string>): string[] {
    if (!dependency.isLocal()) {
      const pkgJson = dependency.getPackageJsonObj() as any;
      return (pkgJson.metadata?.runtimeOnly?.packages || []) as string[];
    }
    const buildOpt = getLocalDependencyBuildOptions(dependency, moduleName2TargetName);
    return buildOpt?.arkOptions?.runtimeOnly?.packages || [];
  }

  private processAllImportees(): void {
    if (!this.isBundledDependencies) {
      return;
    }
    const dependencies = this.service.getAffectsCompilationDependencies();
    const compileDependencyKeySet = new Set<string>(this.targetService.getBuildOption()?.arkOptions?.runtimeOnly?.packages);
    const moduleName2TargetName = HarTargetUtil.calDepHarTargets(this.targetService);
    const importeesPath = this.getImporteesCachePath(COMPILED_IMPORTEE_CACHE_FILE_NAME);
    this.processImportees(importeesPath, dependencies, (importee: string, dependencyType: DependencyType, dependency: Dependency) => {
      compileDependencyKeySet.add(dependency.getDependencyName());
      // 已经被编进abc中的源码HAR
      if (dependency.isHarDependency() && !dependency.isByteCodeHarDependency()) {
        this.getDependencyRuntimePackages(dependency, moduleName2TargetName).forEach(name => compileDependencyKeySet.add(name));
      }
    });
    const compileDependencyKeys = Array.from(compileDependencyKeySet);
    compileDependencyKeys.sort((a, b) => (a > b ? 1 : -1));
    this.affectsCompilationDependencyKeys = compileDependencyKeys;
  }

  private collectNonEntryImportees() {
    // 非字节码HAR不处理，如果字节HAR的同时开启了bundledDependencies，也无需处理
    if (!this.targetService.isByteCodeHar() || this.isBundledDependencies) {
      return;
    }
    const importeeSet = new Set<string>();
    const dependencies = this.isByteCodeHarOptimize ? this.service.getAllDirectDependencies() : this.service.getDirectDependencies();
    const importeesPath = this.getImporteesCachePath(NON_ENTRY_IMPORTEE_CACHE_FILE_NAME);
    this.processImportees(importeesPath, dependencies, (importee: string, dependencyType: DependencyType) => {
      // 只收集三方包
      if (dependencyType !== DependencyType.DEPENDENCY_TYPE_OTHER) {
        return;
      }
      importeeSet.add(importee);
    });
    const importees = Array.from(importeeSet);
    // 排序，保持增量稳定性
    importees.sort((a, b) => (a > b ? 1 : -1));
    this.nonEntryImportees = importees;
  }

  /**
   * 如果开启了bundledDependencies，收集三方库和已compiled的源码HAR
   * @private
   */
  private collectCompiledAndNpmImportees() {
    if (!this.isBundledDependencies) {
      return;
    }
    const dependencies = this.isByteCodeHarOptimize ? this.service.getAffectsCompilationDependencies() : this.service.getAllDependencies();
    const compiledSet: Set<string> = new Set<string>(); // 收集已经compiled的源码HAR
    const npmSet: Set<string> = new Set<string>(); // 收集三方库
    const importeesPath = this.getImporteesCachePath(COMPILED_IMPORTEE_CACHE_FILE_NAME);
    this.processImportees(importeesPath, dependencies, (importee: string, depType: DependencyType, dep: Dependency) => {
      if (depType === DependencyType.DEPENDENCY_TYPE_OTHER) {
        // 以包名进行import的，不需要收集
        if (importee !== dep.getDependencyName()) {
          npmSet.add(importee);
        }
        return;
      }
      if (depType === DependencyType.DEPENDENCY_TYPE_HAR && !dep.isByteCodeHarDependency()) {
        compiledSet.add(importee);
      }
    });
    const compiledImportees: string[] = Array.from(compiledSet);
    const npmImportees: string[] = Array.from(npmSet);
    compiledImportees.sort((a, b) => (a > b ? 1 : -1));
    npmImportees.sort((a, b) => (a > b ? 1 : -1));
    this.compiledPackageNames = compiledImportees;
    this.npmImportees = npmImportees;
  }

  /**
   * 判断有无c++产物，目前的逻辑，除了以.a结尾的，都当做c++产物处理
   * @private
   */
  private hasSoFile() {
    const dirs: string[] = [this.processedLibs];
    while (dirs.length) {
      const dir = dirs.pop()!;
      for (const name of fse.readdirSync(dir)) {
        const filePath = path.resolve(dir, name);
        const lstat = fse.lstatSync(filePath);
        if (lstat.isFile() && !name.endsWith('.a')) {
          return true;
        }
        if (lstat.isDirectory()) {
          dirs.push(filePath);
        }
      }
    }
    return false;
  }

  private copyPkgTypesFilePath(pkgJson: any) {
    const pkgTypes = pkgJson.types;
    if (pkgTypes) {
      const pkgTypesFilePath = path.resolve(this.moduleModel.getModule().getNodeDir(), pkgTypes);
      const copyfile = path.resolve(this.taskTmpDir, pkgTypes);
      fse.ensureDirSync(path.dirname(copyfile));
      if (fse.existsSync(pkgTypesFilePath)) {
        fse.copyFileSync(pkgTypesFilePath, copyfile);
      }
    }
  }

  private forEachDependencies(dependencies: Dependency[], callback: (depName: string, depVersion: string) => void) {
    dependencies.forEach((dept) => {
      const deptType = dept.getDependencyType();
      if (deptType === DependencyType.DEPENDENCY_TYPE_HAR || deptType === DependencyType.DEPENDENCY_TYPE_OTHER) {
        callback(dept.getDependencyName(), dept.getDependencyVersion());
      }
    });
  }

  /**
   * 设置pkgJson中的dependencyPkgVersion
   * @param pkgJson
   * @private
   */
  private setDependencyPkgVersion(pkgJson: any) {
    const pathParamsObj: pathParamsOpt = {
      parameterFilePath: this.service.getProjectModel().getParameterFileAbsolutePath(),
      ohPackageFilePath: this.isOhpmProject ? this.moduleModel.getOhPackageJson5Path() : this.moduleModel.getPackageJsonPath(),
    };

    // bundleHar 如果没有记录到compiledPackageNames的依赖需记录到这里
    if (this.isBundledDependencies) {
      pkgJson.metadata.dependencyPkgVersion ||= {};
      this.forEachDependencies(this.targetService.getModuleService().getAllDependencies(), (depName, depVersion) => {
        if (!this.compiledPackageNames.includes(depName)) {
          pkgJson.metadata.dependencyPkgVersion[depName] =
            FileUtil.extracted(depVersion, this.moduleModel.getParentProject().getParameterFileObj(), pathParamsObj);
        }
      });
      return;
    }

    if (this.targetService.isByteCodeHar()) {
      // 不管有没有其他har依赖，先赋一个空值
      pkgJson.metadata.dependencyPkgVersion ||= {};
      this.forEachDependencies(this.targetService.getModuleService().getDirectDependencies(), (depName, depVersion) => {
        pkgJson.metadata.dependencyPkgVersion[depName] =
          FileUtil.extracted(depVersion, this.moduleModel.getParentProject().getParameterFileObj(), pathParamsObj);
      });
    }
  }

  private traverseToSetOptimizePkgVersion(dependencies: Dependency[], pkgJson: any, pathParamsObj: pathParamsOpt, shouldSet: (dependency: Dependency) => boolean) {
    dependencies.forEach(dependency => {
      if (!shouldSet(dependency)) {
        return;
      }

      // 检测是否用到
      const dependencyKey = dependency.getDependencyName();
      if (this.affectsCompilationDependencyKeys.includes(dependencyKey)) {
        pkgJson.metadata.dependencyPkgVersion[dependencyKey] =
          FileUtil.extracted(dependency.getDependencyVersion(), this.moduleModel.getParentProject().getParameterFileObj(), pathParamsObj);
      }
    })
  }

  /**
   * 设置pkgJson中的dependencyPkgVersion
   * @param pkgJson
   * @private
   */
  private setOptimizeDependencyPkgVersion(pkgJson: any) {
    if (!this.targetService.isByteCodeHar()) {
      return;
    }

    pkgJson.metadata.dependencyPkgVersion ||= {};
    const pathParamsObj: pathParamsOpt = {
      parameterFilePath: this.service.getProjectModel().getParameterFileAbsolutePath(),
      ohPackageFilePath: this.isOhpmProject ? this.moduleModel.getOhPackageJson5Path() : this.moduleModel.getPackageJsonPath(),
    };

    // bundleHar 如果没有记录到bundledDependencyKeys的依赖需记录到这里
    if (this.isBundledDependencies) {
      const dependencies = this.service.getAffectsCompilationDependencies();
      this.traverseToSetOptimizePkgVersion(dependencies, pkgJson, pathParamsObj, dependency => dependency.isByteCodeHarDependency() || dependency.isOtherDependency());
      return;
    }

    const dependencies = this.service.getAllDirectDependencies();
    this.traverseToSetOptimizePkgVersion(dependencies, pkgJson, pathParamsObj, dependency => dependency.isHarDependency() || dependency.isOtherDependency());
  }

  /**
   * 针对自定义的types，如果配置了包名或模块外的路径，做warning提示
   * @param customTypes
   */
  validateCustomTypes(customTypes: string[]) {
    const dependencies = this.getDependencies(this.moduleModel, true);
    const warningTypes: string[] = [];
    customTypes.forEach(type => {
      if (dependencies[type] || dependencies[`@types/${type}`]) {
        warningTypes.push(type);
        return;
      }
      const filePath = getCustomTypePathIfExists(this.moduleModel.getProjectDir(), type);
      // 这个必定会存在，PreBuild校验过，加个判断规避ts报错
      if (!filePath) {
        return;
      }
      if (!isSubPath(fse.realpathSync.native(filePath), this.moduleModel.getProjectDir())) {
        warningTypes.push(type);
      }
    });
    if (!warningTypes.length) {
      return;
    }
    this.logger.warn(`The files of '[${warningTypes.join(',')}]' configured at 'types' field in 'build-profile.json5' are outside of current module. Recommended to migrate these files to the current module's directory for packaging. `);
  }

  private processMetadata(pkgJson: any) {
    if (this.globalAffectsCompilationDependencyKeys.length) {
      pkgJson.metadata.globalDependencies = this.globalAffectsCompilationDependencyKeys;
    }
    if (this.nonEntryImportees.length) {
      pkgJson.metadata.extraImportees = this.nonEntryImportees;
    }
    if (this.isBundledDependencies) {
      pkgJson.metadata.compiledPackageNames = this.compiledPackageNames;
      pkgJson.metadata.extraImportees = this.npmImportees;
    }
    if (this.hasSoFile()) {
      pkgJson.metadata.nativeDebugSymbol = this.isNativeStripped;
    }
    const isOpenSourceHar = !(this._harExtendInfo.isObfuscatedHar() || this.targetService.isByteCodeHar());
    if (isOpenSourceHar && this.customTypes?.length) {
      this.validateCustomTypes(this.customTypes);
      pkgJson.metadata.customTypes = this.customTypes;
    }

    // pkgJson中添加表示本模块使用的arkTs版本号
    pkgJson.metadata.arkTSVersion = this.targetService.getSelfArkTSVersion();
  }

  processPackageJson() {
    const pkgJsonFileName = path.basename(this.packageManagerPath);
    const pkgJsonPath = path.resolve(this.taskTmpDir, pkgJsonFileName);
    if (!fse.existsSync(pkgJsonPath)) {
      return;
    }
    const pkgJson = getJson5Obj(pkgJsonPath);
    this.copyPkgTypesFilePath(pkgJson);
    if (!pkgJson.metadata) {
      pkgJson.metadata = {};
    }
    const sourceRoots = [...(this.targetData.getTargetOpt().source?.sourceRoots || []), `./${BuildDirConst.SRC}/${BuildDirConst.MAIN}`];
    Object.assign(pkgJson.metadata, { sourceRoots, debug: this.targetService.isDebug() });
    this.targetService.getModuleService().getOhpmDependencyInfo();
    this.isByteCodeHarOptimize ? this.setOptimizeDependencyPkgVersion(pkgJson) : this.setDependencyPkgVersion(pkgJson);

    if (this.isBundledDependencies) {
      // 添加bundleDependencies
      Object.assign(pkgJson.metadata, { bundleDependencies: this.isBundledDependencies });

      // 添加本地/远程依赖源码har的resource资源目录
      if (this.ohPkgMetadataResDir && this.ohPkgMetadataResDir.length !== 0) {
        const newOhPkgMetadataResDir: string[] = [];
        this.ohPkgMetadataResDir.forEach((dir) => {
          newOhPkgMetadataResDir.push(path.normalize(dir));
        });
        const resource = {
          directories: newOhPkgMetadataResDir,
        };
        Object.assign(pkgJson.metadata, { resource });
      }

      // dependencies过滤本地远程源码har
      const pkgDependencies = pkgJson.dependencies;
      if (pkgDependencies) {
        this.deleteOhPkgDep(DependencyEnum.DEPENDENCIES, pkgJson);
      }

      // 删除devDependencies
      if (pkgJson.devDependencies) {
        delete pkgJson.devDependencies;
      }

      // dynamicDependencies过滤本地远程源码har
      const pkgDynamicDependencies = pkgJson.dynamicDependencies;
      if (pkgDynamicDependencies) {
        this.deleteOhPkgDep(DependencyEnum.DYNAMIC_DEPENDENCIES, pkgJson);
      }
    }

    if (this.compatibleSdkVersionStage) {
      pkgJson.compatibleSdkVersionStage = this.compatibleSdkVersionStage;
    }

    this.processDeclarationEntry(pkgJson);
    this.processMetadata(pkgJson);
    fse.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson));
  }

  processSourceMaps() {
    if (!this.targetService.isByteCodeHar()) {
      return;
    }
    const shouldPackSourceMaps = this.shouldPackSourceMaps;
    const sourceMapsPath = path.join(this.taskTmpDir, CodeType.ETS, BuildArtifactConst.SOURCEMAPS_MAP);
    if (fse.existsSync(sourceMapsPath)) {
      if (!shouldPackSourceMaps) {
        fse.removeSync(sourceMapsPath);
        this.logger.debug(`Remove '${BuildArtifactConst.SOURCEMAPS_MAP}' from package dir.`);
      }
      return;
    }
    // sourceMaps.map不在，又不需要打包，直接返回
    if (!shouldPackSourceMaps) {
      return;
    }
    const originSourceMapsPath = this.pathInfo.getSourceMapOriginPath(this.targetService);
    if (!fse.existsSync(originSourceMapsPath)) {
      this.logger.debug(`'${BuildArtifactConst.SOURCEMAPS_MAP}' does not exist.`);
      return;
    }
    fse.copyFileSync(originSourceMapsPath, sourceMapsPath);
  }

  /**
   * 删除dependencies或dynamicDependencies中的源码har依赖,保留直接或间接的字节码har和hsp
   * @param dependencyEnum
   * @param pkgJson
   * @private
   */
  private deleteOhPkgDep(dependencyEnum: DependencyEnum, pkgJson: any): void {
    if (!this.targetService.isByteCodeHar() || !this.isBundledDependencies || getPropertyKeepDependency()) {
      return;
    }

    // 收集所有本地/远程/直接/间接依赖
    const pkgDependencyEnumObj = pkgJson[dependencyEnum];
    this.service.getAllDependencies().forEach((dependency) => {
      const depPackageJsonObj: any = dependency.getPackageJsonObj();
      if (!depPackageJsonObj) {
        return;
      }
      Object.assign(pkgDependencyEnumObj, depPackageJsonObj[dependencyEnum]);
    });

    // oh-package.json5的dependencies/dynamicDependencies仅保留hsp或byteCodeHar,删除所有源码har,包括本地/远程/直接/间接依赖
    const hspOrByteCodeHarDepNameArr = this.service.getHspOrByteCodeHarDependencies().map((dependency) => {
      return dependency.getDependencyName();
    });
    for (const dependenciesKey in pkgDependencyEnumObj) {
      if (!hspOrByteCodeHarDepNameArr.includes(dependenciesKey)) {
        delete pkgDependencyEnumObj[dependenciesKey];
      }
    }
  }

  /**
   * 收集本地或远程源码har依赖动态import(sources/packages)的ohmurl写入declarationEntry
   * @param pkgContextInfos
   * @param declarationEntry
   * @private
   */
  private collectRuntimeOnlyOhmurl(pkgContextInfos: any, declarationEntry: string[]) {
    // 生成本地 远程依赖源码har的runtimeOnly的sources和packages的ohmurl
    const depRuntimeOnlyObj = HarTargetUtil.getDep2ConfigMap(this.targetService)?.dep2RuntimeOnlyObj;
    if (!depRuntimeOnlyObj) {
      return;
    }

    // runtimeOnly-sources
    this.collectConfigOhmurl(depRuntimeOnlyObj.dep2RuntimeOnlySources, pkgContextInfos, declarationEntry);

    // runtimeOnly-packages
    const depRuntimeOnlyPackagesOhmurlArr: string[] = [];
    depRuntimeOnlyObj.dep2RuntimeOnlyPackages.forEach((runtimeOnlyPackages) => {
      runtimeOnlyPackages.forEach((dynamicImport) => {
        const dependency = this.service.getHarDependencies().find((harDep) => {
          return harDep.getDependencyName() === dynamicImport;
        });
        if (!dependency) {
          return;
        }

        const dependencyPkgName = DependencyManager.getModuleNameFromOhPkgJson(dependency.getDependencyRootPath());
        const sourceFile = getJson5Obj(dependency.getPackageFilePath()).main ? dependency.getDependencyMainFilePath() : dependency.getDependencyTypesFilePath();
        const runtimeOnlyPkgOhmurlArr = generateOhmUrlForSourceFile(pkgContextInfos[dependencyPkgName], path.relative(`${dependencyPkgName}`, sourceFile));
        depRuntimeOnlyPackagesOhmurlArr.push(runtimeOnlyPkgOhmurlArr);
      });
    });

    declarationEntry.push(...depRuntimeOnlyPackagesOhmurlArr);
  }

  /**
   * 获取worker/runtimeOnly-sources/routerMapObj-pageSourceFile的ohmurl并写入declarationEntry
   * @param dep2ConfigMap
   * @param pkgContextInfos
   * @param declarationEntry
   * @private
   */
  private collectConfigOhmurl(
    dep2ConfigMap: Map<Dependency, string[]> | undefined,
    pkgContextInfos: { [key: string]: PkgContextInfoOpt },
    declarationEntry: string[],
  ): void {
    const configOhmurlArr: string[] = [];
    if (!dep2ConfigMap?.size) {
      return;
    }

    dep2ConfigMap.forEach((configArr, dependency) => {
      const dependencyPkgName = DependencyManager.getModuleNameFromOhPkgJson(dependency.getDependencyRootPath());
      configArr.forEach((config) => {
        const configOhmurl = generateOhmUrlForSourceFile(pkgContextInfos[dependencyPkgName], config.replace(/^\.\//, ''));
        configOhmurlArr.push(configOhmurl);
      });
    });

    declarationEntry.push(...configOhmurlArr);
  }

  protected async doTaskAction(): Promise<void> {
    const allDependency = this.service.getAllDependencies();
    ValidateUtil.validateLocalDependency(this.moduleModel, this.targetService.getBuildOption(), allDependency);

    // 系统级hsp校验 不支持打包hap包
    validatePackageBySystemHspModel(this.service, this.appOptObj, this.targetJsonPath, this.targetModuleOptObj);
    return super.doTaskAction();
  }

  /**
   * 处理混淆har场景下的页面动态路由pageSourceFile
   * 拼接模块真实name,修改原始文件后缀,路径分隔符标准化处理
   * @param moduleModel
   * @param routerMapObj
   * @param obfNameCacheJsonObj
   * @private
   */
  private getObfuscatedPageSourceFile(moduleModel: CoreModuleModelImpl, routerMapObj: RouterMapObj, obfNameCacheJsonObj: any): string | undefined {
    // 获取模块真实name
    const realModuleName = moduleModel
      .getModule()
      .getNodeDir()
      .substring(this.projectModel.getProjectDir().length + 1);

    // pageSourceFile前拼接模块真实name
    const pageSourceFileWithModuleName = `${realModuleName}${path.sep}${routerMapObj.pageSourceFile}`;

    // pageSourceFile替换js为原始后缀
    const pageSourceFileWithOriginalSuffix = pageSourceFileWithModuleName.replace(path.extname(pageSourceFileWithModuleName), routerMapObj.originalSuffix!);

    // pageSourceFile标准化
    const normalizedPageSourceFile = FileUtil.normalizePathSeparator(pageSourceFileWithOriginalSuffix);

    // 通过build/${productName}/cache/default/${targetName}@HarCompileArkTS/esmodule/release/obfuscation/nameCache.json找出pageSourceFile对应的混淆后的路径

    if (!Object.prototype.hasOwnProperty.call(obfNameCacheJsonObj, normalizedPageSourceFile)) {
      return undefined;
    }
    const obfuscatedPageSourceFile = obfNameCacheJsonObj[normalizedPageSourceFile].obfName;

    // 重写写回路由表的对象pageSourceFile需去除模块name
    const pageSourceFileWithoutModuleName = obfuscatedPageSourceFile.substring(realModuleName.length + 1);

    // 修改pageSourceFile后缀
    return pageSourceFileWithoutModuleName.replace(path.extname(pageSourceFileWithoutModuleName), this.hasUseTsHarField() ? '.ts' : '.js');
  }

  /**
   * 收集字节码har的abilities数组中ability对象的srcEntry并转换为ohmurl写入declarationEntry
   *
   * @param pkgContextInfos
   * @param declarationEntry
   * @private
   */
  private collectByteCodeHarAbilityOhmurl(
    pkgContextInfos: {
      [key: string]: PkgContextInfoOpt;
    },
    declarationEntry: string[],
  ) {
    const moduleJsonObj = resModelLoader.getModuleJson(this.targetJsonPath);

    for (const abilityTypeName of [this.abilities, this.extensionAbilities]) {
      const moduleAbilities = moduleJsonObj?.module[abilityTypeName] as ModuleJson.AbilityObj[] | undefined;

      if (!moduleAbilities?.length) {
        continue;
      }

      moduleAbilities.forEach((abilityObj: ModuleJson.AbilityObj) => {
        if (!abilityObj?.srcEntry) {
          return;
        }

        const absoluteSrcEntryPath = this.targetService.getAbsoluteSrcEntryPath(abilityObj.srcEntry, this.module.getNodeDir());
        if (!fse.existsSync(absoluteSrcEntryPath)) {
          this.logger.debug('The srcEntry path for obtaining the ability of the module is incorrect or the corresponding file does not exist.');
          return;
        }

        const configOhmurl = generateOhmUrlForSourceFile(pkgContextInfos[this.packageJsonObj.name], absoluteSrcEntryPath.substring(this._moduleDir.length + 1));
        declarationEntry.push(configOhmurl);
      });
    }
  }

  /**
   * 字节码har支持启动框架业务处理：将startupTasks中每一项srcEntry对应的绝对路径转换成对应ohmurl写入declarationEntry字段
   * intermediateTempStartupFilePath中数据进行处理，如果是bundleDependencies har会包含合并后的所有startupTasks
   *
   * @param declarationEntry
   * @private
   */
  private collectByteCodeHarStartupTasks(declarationEntry: string[]) {
    if (!fse.existsSync(this.intermediateTempStartupFilePath)) {
      return;
    }
    const startupMergedOptions: StartupOptions | undefined = getJson5Obj(this.intermediateTempStartupFilePath);
    if (startupMergedOptions === undefined) {
      return;
    }
    startupMergedOptions.startupTasks?.forEach((startupTask) => {
      declarationEntry.push(startupTask.ohmurl ?? startupTask.srcEntry);
    });
  }

  /**
   * 字节码har收集意图框架入口文件，将这些ohmurl收集到declarationEntry里
   * 对于非bundle的，只需要收集本身，bundle的则需要依赖链上的所有意图框架入口的ohmurl
   *
   * @param pkgContextInfos
   * @param declarationEntry
   * @private
   */
  private collectByteCodeHarInsightIntentSrcEntry(
    pkgContextInfos: {
      [key: string]: PkgContextInfoOpt;
    },
    declarationEntry: string[],
  ) {
    if (!fse.existsSync(this.insightIntentJsonPath)) {
      return;
    }

    const insightIntentJsonObj = getJson5Obj(this.insightIntentJsonPath);
    // 先处理自身的意图框架入口,同样只处理新的意图框架入口，旧的不做处理
    for (const intent of [...(insightIntentJsonObj.insightIntentsSrcEntry ?? [])]) {
      const absoluteSrcEntryPath = this.targetService.getAbsoluteSrcEntryPath(intent.srcEntry, this.module.getNodeDir());
      declarationEntry.push(generateOhmUrlForSourceFile(pkgContextInfos[this.packageJsonObj.name], path.relative(this.module.getNodeDir(), absoluteSrcEntryPath)));
    }

    // 如果是bundleDependencies，则依赖链路上的也需要收集ohmurl
    if (this.isBundledDependencies) {
      const depHar = this.service.getHarDependencies();

      depHar.forEach(dep => {
        const insightIntentJsonPath = dep.getInsightIntentPath();
        if (dep.isByteCodeHarDependency() || !fse.existsSync(insightIntentJsonPath)) {
          return;
        }
        const insightIntentDataJson = getJson5Obj(insightIntentJsonPath);
        for (const intent of [...(insightIntentDataJson.insightIntentsSrcEntry ?? [])] ) {
          if (intent.srcEntry) {
            const absoluteSrcEntryPath = this.targetService.getAbsoluteSrcEntryPath(intent.srcEntry, dep.getDependencyRootPath());
            declarationEntry.push(generateOhmUrlForSourceFile(pkgContextInfos[this.packageJsonObj.name], path.relative(dep.getDependencyRootPath(), absoluteSrcEntryPath)));
          }
        }
      });
    }
  }

  /**
   * 处理混淆har模块ability
   * 1..har产物的module.json/abilities/srcEntry的后缀转换成.js
   * 2.若开启路径混淆,.har产物的module.json/abilities/srcEntry根据混淆的namecache转换成混淆后的js路径
   * 3.useTsHar时上述1/2场景中.js后缀修改为.ts
   * @private
   */
  processObfuscatedHarAbility() {
    if (!this.moduleModel.isHarModule() || this.targetService.isOpenSource()) {
      return;
    }

    // 处理混淆har的abilities
    const tempModuleJsonPath = path.resolve(this.taskTmpDir, BuildDirConst.SRC, BuildDirConst.MAIN, CommonConst.MODULE_JSON);
    if (!fse.existsSync(tempModuleJsonPath)) {
      this.logger.debug('Failed to obtain the module.json file from the module intermediate product.');
      return;
    }

    const moduleJsonObj = getJson5Obj(tempModuleJsonPath);

    for (const abilityTypeName of [this.abilities, this.extensionAbilities]) {
      const moduleAbilities = moduleJsonObj?.module[abilityTypeName];
      if (!moduleAbilities?.length) {
        continue;
      }

      moduleAbilities.forEach((abilityObj: ModuleJson.AbilityObj) => {
        if (!abilityObj?.srcEntry) {
          return;
        }

        const obfuscatedHarAbilitySrcEntry = this.getObfuscatedHarAbilitySrcEntry(abilityObj.srcEntry, this.getObfNameCacheObj());
        Object.assign(abilityObj, {
          srcEntry: obfuscatedHarAbilitySrcEntry,
        });
      });
    }

    fse.writeJSONSync(tempModuleJsonPath, moduleJsonObj);
  }

  /**
   * 根据混淆配置映射获取混淆后的ability-srcEntry路径
   * @param originalSrcEntry
   * @param obfNameCacheJsonObj
   * @private
   */
  private getObfuscatedHarAbilitySrcEntry(originalSrcEntry: string, obfNameCacheJsonObj: any): string | undefined {
    const absoluteSrcEntryPath = this.targetService.getAbsoluteSrcEntryPath(originalSrcEntry, this.module.getNodeDir());
    if (!fse.existsSync(absoluteSrcEntryPath)) {
      this.logger.debug('The srcEntry path for obtaining the ability of the module is incorrect or the corresponding file does not exist.');
      return;
    }

    // 混淆映射表中srcEntry key格式:{moduleName}/src/main/{originalSrcEntry}
    const nameCacheKey = toUnixPath(absoluteSrcEntryPath).substring(this.projectDir.length + 1);
    if (!Object.prototype.hasOwnProperty.call(obfNameCacheJsonObj, nameCacheKey)) {
      return undefined;
    }

    const currentDir = path.dirname(this.targetJsonPath);
    const obfuscatedSrcEntry = obfNameCacheJsonObj[nameCacheKey].obfName;
    if (currentDir === '' || !currentDir || obfuscatedSrcEntry === '' || !obfuscatedSrcEntry) {
      return undefined;
    }
    const relativeSrcEntryPath = path.relative(currentDir, path.resolve(this.projectDir, obfuscatedSrcEntry));
    const replacePathSep = `./${relativeSrcEntryPath.replace(/\\/g, '/')}`;
    return replacePathSep.replace(path.extname(replacePathSep), this.hasUseTsHarField() ? '.ts' : '.js');
  }

  /**
   * 获取模块混淆配置映射对象
   * @private
   */
  private getObfNameCacheObj(): any {
    const obfNameCacheFilePath = path.resolve(
      this.pathInfo.getModuleBuildCachePath(),
      `${this.targetName}@HarCompileArkTS`,
      'esmodule',
      'release',
      'obfuscation',
      'nameCache.json',
    );

    return getJson5Obj(obfNameCacheFilePath);
  }

  copyDeclgenToTempDir(): void {
    const declgenV2OutPath = this.pathInfo.getIntermediatesDeclgenPath(this.packageJsonObj.name);
    if (!fse.existsSync(declgenV2OutPath) || !fse.statSync(declgenV2OutPath).isDirectory()) {
      return;
    }
    fse.ensureDirSync(this.taskTmpDir);
    fse.copySync(declgenV2OutPath, this.taskTmpDir);
  }
}
